<!--
 * 列表、加载状态、空状态
 * @作者: 陈老师儿~
 * @手机: 18560000860
 -->
<template>
    <view class="pure-list" :class="classes" :style="styles">
        <!-- 列表 -->
        <slot></slot>

        <!-- 空状态 -->
        <view class="pure-list-empty" v-if="isEmpty && showEmpty">
            <pure-empty v-bind="emptyOpts"></pure-empty>
        </view>

        <!-- 加载状态 -->
        <view class="pure-list-loadmore" v-if="!isEmpty && showLoadmore">
            <pure-loadmore v-bind="loadmoreOpts" :status="loadStatus" @onClick="load"></pure-loadmore>
        </view>
    </view>
</template>

<script>
    import props from "./props.js";
    import { isFunction } from "@/uni_modules/pure-functions";

    export default {
        options: {
            // 将自定义节点设置成虚拟的
            // 头条、飞书：因为合并后丢失事件和 'provide/inject'
            // 京东：因为合并后不能合并外层 'class'
            // 百度：因为合并后会在控制台疯狂报警告
            // #ifndef MP-TOUTIAO || MP-LARK || MP-JD || MP-BAIDU
            virtualHost: true,
            // #endif

            // 组件样式隔离
            styleIsolation: "apply-shared",

            // 允许使用多个插槽
            multipleSlots: true,
        },
        props: props,
        emits: ["update:modelValue", "complete"],
        data() {
            return {
                // 当前页码
                pageIndex: 1,
                // 加载状态
                loadStatus: "more",
            };
        },
        computed: {
            // classes
            classes() {
                const classes = [];
                return classes;
            },

            // styles
            styles() {
                const styles = [];
                return styles;
            },

            // 是否数据为空
            isEmpty() {
                return (this.loadStatus === "nomore" || this.loadStatus === "fail") && this.pageIndex === this.defaultIndex;
            },
        },
        create() {
            // 默认页码
            this.pageIndex = this.defaultIndex;
        },
        methods: {
            // 加载数据
            load() {
                if (!isFunction(this.loadPromise)) return;

                // 正在加载
                if (this.loadStatus === "loading") return;

                // 没有更多了
                if (this.loadStatus === "nomore") return;

                // 更新加载状态
                this.loadStatus = "loading";

                // 加载数据
                this.loadPromise()
                    .then((res) => {
                        // 获取列表数据
                        const list = this.getListData(res);

                        // 数据异常，请求失败
                        if (list === undefined) {
                            // 更新加载状态
                            this.loadStatus = "fail";
                            return;
                        }

                        // 如果数据为空，则认为没有更多数据
                        if (list.length === 0) {
                            this.loadStatus = "nomore";
                            return;
                        }

                        // 更新数据
                        const newList = this.updateData(list);

                        // 更新页码
                        this.pageIndex++;

                        // 获取数据的总页数
                        if (this.pageTotalKeyName) {
                            const pageCount = this.getPageCount(res);

                            // 判断是否有下一页
                            if (this.pageIndex >= pageCount) this.loadStatus = "nomore";
                            else this.loadStatus = "more";

                            return;
                        }

                        // 获取数据的总长度
                        if (this.listTotalKeyName) {
                            const listTotal = this.getListTotal(res);

                            // 判断是否有下一页
                            if (newList.length >= listTotal) this.loadStatus = "nomore";
                            else this.loadStatus = "more";

                            return;
                        }

                        // 默认，通过返回新数据的长度和每页的长度判断是否有下一页
                        // 只要新数据的长度小于每页长度，则认为没有下一页
                        if (list.length < this.pageSize) this.loadStatus = "nomore";
                        else this.loadStatus = "more";
                    })
                    .catch((err) => {
                        // 更新加载状态
                        this.loadStatus = "fail";
                    })
                    .finally(() => {
                        // 结束下拉刷新
                        uni.stopPullDownRefresh();

                        // 提交事件
                        this.$emit("complete");
                    });
            },

            // 刷新数据
            refresh() {
                this.$emit("update:modelValue", []);
                this.pageIndex = this.defaultIndex;
                this.loadStatus = "more";
                this.load();
            },

            // 获取接口返回的列表数据
            getListData(res = {}) {
                // 分割 keyName
                const keys = this.listDataKeyName.split(".");

                // 初始化当前对象为 res
                let currentObj = res;

                // 循环访问对象属性
                for (let i = 0; i < keys.length; i++) {
                    const key = keys[i];
                    if (currentObj.hasOwnProperty(key)) {
                        currentObj = currentObj[key];
                    } else {
                        // 如果属性不存在，返回 undefined
                        currentObj = undefined;
                        break;
                    }
                }

                return currentObj;
            },

            // 更新数据
            updateData(list) {
                const newList = this.modelValue.concat(list);
                this.$emit("update:modelValue", newList);
                return newList;
            },

            // 获取数据的总页数
            getPageCount(res = {}) {
                // 分割 keyName
                const keys = this.pageTotalKeyName.split(".");

                // 初始化当前对象为 res
                let currentObj = res;

                // 循环访问对象属性
                for (let i = 0; i < keys.length; i++) {
                    const key = keys[i];
                    if (currentObj.hasOwnProperty(key)) {
                        currentObj = currentObj[key];
                    } else {
                        // 如果属性不存在，返回 undefined
                        currentObj = 0;
                        break;
                    }
                }

                return Number(currentObj);
            },

            // 获取数据的总长度
            getListTotal(res = {}) {
                // 分割 keyName
                const keys = this.listTotalKeyName.split(".");

                // 初始化当前对象为 res
                let currentObj = res;

                // 循环访问对象属性
                for (let i = 0; i < keys.length; i++) {
                    const key = keys[i];
                    if (currentObj.hasOwnProperty(key)) {
                        currentObj = currentObj[key];
                    } else {
                        // 如果属性不存在，返回 undefined
                        currentObj = 0;
                        break;
                    }
                }

                return Number(currentObj);
            },
        },
        expose: ["load", "refresh"],
    };
</script>
